home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 292_03 / lkeval.c < prev    next >
C/C++ Source or Header  |  1990-07-16  |  4KB  |  257 lines

  1. /* lkeval.c */
  2.  
  3. /*
  4.  * (C) Copyright 1989,1990
  5.  * All Rights Reserved
  6.  *
  7.  * Alan R. Baldwin
  8.  * 721 Berkeley St.
  9.  * Kent, Ohio  44240
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <alloc.h>
  15. #include "aslink.h"
  16.  
  17. /*
  18.  * Evaluate input term.
  19.  */
  20. addr_t
  21. eval()
  22. {
  23.     register c, v;
  24.     register addr_t n;
  25.  
  26.     c = getnb();
  27.     n = 0;
  28.     while ((v = digit(c, radix)) >= 0) {
  29.         n = n*radix + v;
  30.         c = get();
  31.     }
  32.     unget(c);
  33.     return(n);
  34. }
  35.  
  36. /*
  37.  * Expression evaluation.
  38.  * `N' is a firewall priority; all top level calls
  39.  * (from the user) should be made with `n' set to 0.
  40.  */
  41. addr_t
  42. expr (n)
  43. {
  44.     register c, p;
  45.     register addr_t v, ve;
  46.  
  47.     v = term();
  48.     while (ctype[c = getnb()] & BINOP) {
  49.         if ((p = oprio(c)) <= n)
  50.             break;
  51.         if ((c == '>' || c == '<') && c != get()) {
  52.             fprintf(stderr, "Invalid expression");
  53.             return(v);
  54.         }
  55.         ve = expr(p);
  56.         if (c == '+') {
  57.             v += ve;
  58.         } else
  59.         if (c == '-') {
  60.             v -= ve;
  61.         } else {
  62.             switch (c) {
  63.  
  64.             case '*':
  65.                 v *= ve;
  66.                 break;
  67.  
  68.             case '/':
  69.                 v /= ve;
  70.                 break;
  71.  
  72.             case '&':
  73.                 v &= ve;
  74.                 break;
  75.  
  76.             case '|':
  77.                 v |= ve;
  78.                 break;
  79.  
  80.             case '%':
  81.                 v %= ve;
  82.                 break;
  83.  
  84.             case '^':
  85.                 v ^= ve;
  86.                 break;
  87.  
  88.             case '<':
  89.                 v <<= ve;
  90.                 break;
  91.  
  92.             case '>':
  93.                 v >>= ve;
  94.                 break;
  95.             }
  96.         }
  97.     }
  98.     unget(c);
  99.     return(v);
  100. }
  101.  
  102. /*
  103.  * Read a term.
  104.  * Handles unary operators, brackets,
  105.  * constants in decimal, octal or hexadecimal
  106.  * and identifiers.
  107.  */
  108. addr_t
  109. term()
  110. {
  111.     register c, r, n;
  112.     register addr_t v;
  113.     struct sym *sp;
  114.     char id[NCPS];
  115.  
  116.     c = getnb();
  117.     if (c == '#') { c = getnb(); }
  118.     if (c == '(') {
  119.         v = expr(0);
  120.         if (getnb() != ')')
  121.             fprintf(stderr, "Missing delimiter");
  122.         return(v);
  123.     }
  124.     if (c == '-') {
  125.         return(-expr(100));
  126.     }
  127.     if (c == '~') {
  128.         return(~expr(100));
  129.     }
  130.     if (c == '\'') {
  131.         return(getmap(-1));
  132.     }
  133.     if (c == '\"') {
  134.         if (hilo) {
  135.             v  = (getmap(-1)&0377)<<8;
  136.             v |=  getmap(-1)&0377;
  137.         } else {
  138.             v  =  getmap(-1)&0377;
  139.             v |= (getmap(-1)&0377)<<8;
  140.         }
  141.         return(v);
  142.     }
  143.     if (c == '>' || c == '<') {
  144.         v = expr(100);
  145.         if (c == '>')
  146.             v >>= 8;
  147.         return(v&0377);
  148.     }
  149.     if (ctype[c] & DIGIT) {
  150.         r = 10;
  151.         if (c == '0') {
  152.             c = get();
  153.             switch (c) {
  154.             case 'b':
  155.             case 'B':
  156.                 r = 2;
  157.                 c = get();
  158.                 break;
  159.             case '@':
  160.             case 'o':
  161.             case 'O':
  162.             case 'q':
  163.             case 'Q':
  164.                 r = 8;
  165.                 c = get();
  166.                 break;
  167.             case 'd':
  168.             case 'D':
  169.                 r = 10;
  170.                 c = get();
  171.                 break;
  172.             case 'h':
  173.             case 'H':
  174.             case 'x':
  175.             case 'X':
  176.                 r = 16;
  177.                 c = get();
  178.                 break;
  179.             default:
  180.                 break;
  181.             }
  182.         }
  183.         v = 0;
  184.         while ((n = digit(c, r)) >= 0) {
  185.             v = r*v + n;
  186.             c = get();
  187.         }
  188.         unget(c);
  189.         return(v);
  190.     }
  191.     if (ctype[c] & LETTER) {
  192.         getid(id, c);
  193.         if ((sp = lkpsym(id, 0)) == NULL) {
  194.             fprintf(stderr, "Undefined symbol %8s\n", id);
  195.             return(0);
  196.         } else {
  197.             return(symval(sp));
  198.         }
  199.     }
  200. }
  201.  
  202. /*
  203.  * If `c' is a legal radix `r' digit
  204.  * return its value; otherwise return
  205.  * -1.
  206.  */
  207. int
  208. digit(c, r)
  209. register c, r;
  210. {
  211.     if (r == 16) {
  212.         if (ctype[c] & RAD16) {
  213.             if (c >= 'A' && c <= 'F')
  214.                 return (c - 'A' + 10);
  215.             if (c >= 'a' && c <= 'f')
  216.                 return (c - 'a' + 10);
  217.             return (c - '0');
  218.         }
  219.     } else
  220.     if (r == 10) {
  221.         if (ctype[c] & RAD10)
  222.             return (c - '0');
  223.     } else
  224.     if (r == 8) {
  225.         if (ctype[c] & RAD8)
  226.             return (c - '0');
  227.     } else
  228.     if (r == 2) {
  229.         if (ctype[c] & RAD2)
  230.             return (c - '0');
  231.     }
  232.     return (-1);
  233. }
  234.  
  235. /*
  236.  * Return the priority of the binary
  237.  * operator `c'.
  238.  */
  239. int
  240. oprio(c)
  241. register c;
  242. {
  243.     if (c == '*' || c == '/' || c == '%')
  244.         return (10);
  245.     if (c == '+' || c == '-')
  246.         return (7);
  247.     if (c == '<' || c == '>')
  248.         return (5);
  249.     if (c == '^')
  250.         return (4);
  251.     if (c == '&')
  252.         return (3);
  253.     if (c == '|')
  254.         return (1);
  255.     return (0);
  256. }
  257.